package za.org.meraka.cair.ontorepair;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.util.SimpleIRIMapper;

//import java.net.URI;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
import java.util.Stack;

public class UtilityClass<T> {	
	public UtilityClass(){}
	
	public String chooseElement(Set<String> set){
		String[] setArr = (String[])set.toArray(new String[set.size()]);
		if (setArr.length > 0)
			return setArr[0];
		else
			return null; 
	}
	
	public Set<Set<T>> getRelevantSets(Set<Set<T>> hs, Stack<Set<T>> stack){
		Set<Set<T>> result = new HashSet<Set<T>>();
		for (Set<T> tmp : hs){
			if (!(stack.contains(tmp))){
				result.add(tmp);
			}
		}		
		return result;
	}
	
	public Integer getIndex(OWLAxiom axiom, OWLOntology ontology) throws OWLException{
		int result = 1;
		for (OWLAxiom ax: ontology.getAxioms()){
   	    	if (ax == axiom){
   	    		return new Integer(result);
   	    	}
   	    	result++;
   	    }		
		return new Integer(-1);
	}	
	
	public OWLOntology removeAxiom(OWLAxiom axiom, OWLOntology ontology) throws OWLException{
		OWLOntology result;
		OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
		
		/******************************Create Temp Ontology********************************/		
		IRI ontologyIRI2 = IRI.create("http://www.meraka.org.za/ontologies/main.owl");
		IRI physicalIRI2 = IRI.create("file:/tmp/main.owl");
   	    SimpleIRIMapper mapper2 = new SimpleIRIMapper(ontologyIRI2, physicalIRI2);
   	    manager.addIRIMapper(mapper2);
   	    
   	    result = manager.createOntology(ontologyIRI2);
   	    
   	    for (OWLAxiom ax: ontology.getAxioms()){
   	    	if (ax != axiom){
   	    		AddAxiom a = new AddAxiom(result, ax);
   	    		manager.applyChange(a);
   	    	}
   	    }
   	    return result;
	}
	
	public OWLOntology removeAxioms(Set<OWLAxiom> axioms, OWLOntology ontology) throws OWLException{
		OWLOntology result;
		OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
		
		/******************************Create Temp Ontology********************************/		
		IRI ontologyIRI2 = IRI.create("http://www.meraka.org.za/ontologies/main.owl");
		IRI physicalIRI2 = IRI.create("file:/tmp/main.owl");
   	    SimpleIRIMapper mapper2 = new SimpleIRIMapper(ontologyIRI2, physicalIRI2);
   	    manager.addIRIMapper(mapper2);
   	    
   	    result = manager.createOntology(ontologyIRI2);
   	       	    
   	    for (OWLAxiom ax: ontology.getAxioms()){   	    
   	    	if (!axioms.contains(ax)){
   	    		AddAxiom a = new AddAxiom(result, ax);
   	    		manager.applyChange(a);
   	    	}
   	    }   	       	       	       	       	   	      	    
   	    return result;
	}
	
	public OWLOntology addAxiom(OWLAxiom axiom, OWLOntology ontology) throws OWLException{
		OWLOntology result;
		OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
		
		/******************************Create Temp Ontology********************************/		
		IRI ontologyIRI2 = IRI.create("http://www.meraka.org.za/ontologies/main.owl");
		IRI physicalIRI2 = IRI.create("file:/tmp/main.owl");
   	    SimpleIRIMapper mapper2 = new SimpleIRIMapper(ontologyIRI2, physicalIRI2);
   	    manager.addIRIMapper(mapper2);
   	    
   	    result = manager.createOntology(ontologyIRI2);
   	    
   	    for (OWLAxiom ax: ontology.getAxioms()){   	    	
   	    	AddAxiom a = new AddAxiom(result, ax);
   	    	manager.applyChange(a);   	    	
   	    }
   	    
   	    AddAxiom b = new AddAxiom(result, axiom);
    	manager.applyChange(b);   	    	   	       	       	      	       	       	   	   
   	    
   	    return result;
	}
	
	public void printPaths(Set<Set<T>> paths){
		Iterator<Set<T>> it1 = paths.iterator();
		while (it1.hasNext()){
			Iterator<T> it2 = it1.next().iterator();
			while (it2.hasNext()){
				System.out.print(it2.next() + ", ");
			}
			System.out.println();
		}
	}
	
	public void printPaths2(Set<Set<OWLAxiom>> paths, OWLOntology ontology) throws OWLException{
		Iterator<Set<OWLAxiom>> it1 = paths.iterator();
		while (it1.hasNext()){
			Iterator<OWLAxiom> it2 = it1.next().iterator();
			while (it2.hasNext()){
				System.out.print(getIndex(it2.next(), ontology) + ", ");
			}
			System.out.println();
		}
	}	
				
	public void printStack(Set<Stack<Integer>> s) {
		Iterator<Stack<Integer>> it1 = s.iterator();
		while (it1.hasNext()){
			Iterator<Integer> it2 = it1.next().iterator();
			while (it2.hasNext()){
				System.out.print(it2.next() + ", ");
			}
			System.out.println();
		}
	}
	
	public Set<T> intersection(Set<T> s1, Set<T> s2){		
		Set<T> intersection = new HashSet<T>(s1);		
		intersection.retainAll(s2);
		return intersection;
	}

	public boolean superSet(Stack<Integer> s, Set<Stack<Integer>> set){
		Iterator<Stack<Integer>> iter = set.iterator();
		while (iter.hasNext()){
			Stack<Integer> tmp = iter.next();
			if (s.containsAll(tmp))
				return true;
		}
		return false;
	}
	
	public Set<Set<T>> rem(Set<T> set, Set<Set<T>> bigSet){
		Set<Set<T>> result = new HashSet<Set<T>>();				
		for (Set<T> tmp: bigSet){
			if (!(tmp.equals(set)))
				result.add(tmp);
		}
		return result;
	}
	
	public Set<OWLOntology> rem2(OWLOntology set, Set<OWLOntology> bigSet){
		Set<OWLOntology> result = new HashSet<OWLOntology>();				
		for (OWLOntology tmp: bigSet){
			if (!(tmp.equals(set)))
				result.add(tmp);
		}
		return result;
	}
	
	public boolean supSet(Set<T> set, Set<Set<T>> bigSet){
		for (Set<T> tmp: bigSet){
			if (set.containsAll(tmp))
				return true;
		}		
		return false;
	}
	
	public boolean supSet2(OWLOntology set, Set<OWLOntology> bigSet){
		Set<OWLAxiom> axioms = set.getAxioms();
		for (OWLOntology tmp: bigSet){
			if (axioms.containsAll(tmp.getAxioms()))
				return true;
		}		
		return false;
	}		
	
	public boolean subSet(Set<T> set, Set<Set<T>> bigSet){
		for (Set<T> tmp: bigSet){
			if (tmp.containsAll(set))
				return true;
		}		
		return false;
	}
	
	public Set<Set<T>> prune(Set<Set<T>> set){
		Set<Set<T>> result = new HashSet<Set<T>>();
		for (Set<T> tmp: set){
			if (!subSet(tmp, rem(tmp, set))){
				result.add(tmp);
			}
		}								
		return result;		
	}
	
	public Set<OWLOntology> prune2(Set<OWLOntology> set){	
		Set<OWLOntology> result = new HashSet<OWLOntology>();
		for (OWLOntology tmp: set){
			if (!supSet2(tmp, rem2(tmp, set))){
				result.add(tmp);
			}
		}								
		return result;		
	}
		
	public char getType(OWLAxiom axiom){
		if (axiom.getAxiomType().toString().equals("SubClass axiom"))
			return 's';
		else if (axiom.getAxiomType().toString().equals("Equivalent classes axiom"))
			return 'e';
		else if (axiom.getAxiomType().toString().equals("Disjoint classes axiom"))
			return 'd';
		else 
			return '1';
	}
}
